﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Services;
using MainGame.SaveData;
using System.Diagnostics;
using MainGame.GameSound;

namespace MainGame.Menu
{

  public interface IKeyboardMenu
  {
    event MenuEvent OnSaveClicked;
    event MenuEvent OnExitClicked;
    event MenuEvent OnExitClickedNoProfile;

  }


  public class KeyboardMenu : BaseMenu, IKeyboardMenu
  {

    Button[] keyboard_buttons;
    Button[] Extra_buttons;
    Button Back, Save, ShadowBox;
    Vector2 savedPos;
    List<string> Profiles;
    public bool Animated = false, ShiftOn = false, PressedOn = false, ExtraOn = false, LongerThenOneChar = false;
    public int Direction = 1, Ipres = 0, Tpres = 0, Epres= 0;
    public bool logged = true, ProfileCreated = false;
    public string word = "";
    public Color color, colorBtn;
    int max_lenght = 8;   
    string[] WordArray = { "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Z", "X", "C", "V", "B", "N", "M" };
    SoundEffect s_logo;
    public bool fromProfile;
    

    SpriteBatch spriteBatch;

    public KeyboardMenu(Game game, MenuDepths depth)
      : base(game, depth)
    {
      spriteBatch = Game.GetContext().SpriteBatch;
      background = game.Content.Load<Texture2D>(@"Images//Backgrounds//Bg_Squares");
      bounds = new Rectangle(0, -game.GraphicsDevice.Viewport.Height, 800, 480);
      game.Services.AddService(typeof(IKeyboardMenu), this);
    }

    protected override void Dispose(bool disposing)
    {
      Game.Services.RemoveService(typeof(IKeyboardMenu));
      base.Dispose(disposing);
    }


    public override void Initialize()
    {
      s_logo = Game.Content.Load<SoundEffect>(@"Sounds//m_logo");
      Profiles = SaveUtils.GetProfileList(Game);
      base.Initialize();
      savedPos.Y = bounds.Y;
      colorBtn = new Color(55, 50, 250);

      //Spazio tra i tasti
      int Gap = 60;
      int HeightGap = 10;
      int StartGap = 62;
      int StartHeight = 190;

      //Buttons
      keyboard_buttons = new Button[27];
      Extra_buttons = new Button[4];

      for (int i = 1; i < 27; i++)
      {
       var curr_i = i;
               

       if (i < 11)
       {
         keyboard_buttons[i] = new Button(Game, @"Images//Menu//button2", new Rectangle(StartGap + (Gap * i), (int)bounds.Y + StartHeight, 50, 50), colorBtn, "large_font", WordArray[i - 1], Color.White);
         AddButton(keyboard_buttons[i], () =>
         {
           PressedOn = true;
           Ipres = curr_i;

           if (word.Length < max_lenght)              
            word += keyboard_buttons[curr_i].message;

           if (word.Length == 0)
             LongerThenOneChar = false;

           if ((word.Length > 0) && (!LongerThenOneChar))
           {
             ShiftOn = true;
             ShadowBox.color = Color.Transparent;
             Extra_buttons[1].bounds = new Rectangle(45, (int)bounds.Y + 255, 85, 85);
           }

           // Play sound
           Random random = new Random();
           var soundManager = Game.Services.GetService(typeof(ISoundManager<MenuSounds>)) as ISoundManager<MenuSounds>;
           soundManager.PlaySound((MenuSounds)random.Next((int)MenuSounds.Keystroke1, (int)MenuSounds.Keystroke3 + 1));
          });
        }
        else if (i > 10 && i < 20)
        {
          keyboard_buttons[i] = new Button(Game, @"Images//Menu//button2", new Rectangle(StartGap + 38 + (Gap * (i - 10)), (int)bounds.Y + StartHeight + 53 + HeightGap, 50, 50), colorBtn, "large_font", WordArray[i - 1], Color.White);
          AddButton(keyboard_buttons[i], () =>
          {
            PressedOn = true;
            Ipres = curr_i;

            if (word.Length < max_lenght)
              word += keyboard_buttons[curr_i].message;

            if (word.Length == 0)
              LongerThenOneChar = false;

            if ((word.Length > 0) && (!LongerThenOneChar))
            {
              ShiftOn = true;
              ShadowBox.color = Color.Transparent;
              Extra_buttons[1].bounds = new Rectangle(45, (int)bounds.Y + 255, 85, 85);
            }

            // Play sound
            Random random = new Random();
            var soundManager = Game.Services.GetService(typeof(ISoundManager<MenuSounds>)) as ISoundManager<MenuSounds>;
            soundManager.PlaySound((MenuSounds)random.Next((int)MenuSounds.Keystroke1, (int)MenuSounds.Keystroke3 + 1));              
          });
        }
        else
        {
          //HeightGap = 19 ;
          keyboard_buttons[i] = new Button(Game, @"Images//Menu//button2", new Rectangle(StartGap + 20 + (Gap * (i - 19)), (int)bounds.Y + StartHeight + 106 + (HeightGap * 2), 50, 50), colorBtn, "large_font", WordArray[i - 1], Color.White);
          AddButton(keyboard_buttons[i], () =>
          {
            PressedOn = true;
            Ipres = curr_i;

            if (word.Length < max_lenght)
              word += keyboard_buttons[curr_i].message;

            if (word.Length == 0)
              LongerThenOneChar = false;

            if ((word.Length > 0) && (!LongerThenOneChar))
            {
              ShiftOn = true;
              ShadowBox.color = Color.Transparent;
              Extra_buttons[1].bounds = new Rectangle(45, (int)bounds.Y + 255, 85, 85);
            }

            // Play sound
            Random random = new Random();
            var soundManager = Game.Services.GetService(typeof(ISoundManager<MenuSounds>)) as ISoundManager<MenuSounds>;
            soundManager.PlaySound((MenuSounds)random.Next((int)MenuSounds.Keystroke1, (int)MenuSounds.Keystroke3 + 1));
          });
        }
      }

      ShadowBox = new Button(Game, @"Images//Game//roundedBox", new Rectangle(bounds.X + 50, bounds.Y + 255, 85, 85), new Color(0, 0, 0, 150), "baveuse_small", Locale.Strings.No, Color.Transparent);
      AddButton(ShadowBox, () =>
      { });

      //SHIFT BUTTON
      Extra_buttons[1] = new Button(Game, @"Images//Menu//button2", new Rectangle(40, (int)bounds.Y + 245, 85, 85), Color.Red, "large_font", Locale.Strings.KeyBoardShift, Color.White, 0.8f);
      AddButton(Extra_buttons[1], () =>
      {
        LongerThenOneChar = true;
        if (ShiftOn)
        {
          ShiftOn = false;
          ShadowBox.color = new Color(0, 0, 0, 150);
          Extra_buttons[1].bounds = new Rectangle(40, (int)bounds.Y + 245, 85, 85);
        }
        else
        {
          ShiftOn = true;
          ShadowBox.color = Color.Transparent;
          Extra_buttons[1].bounds = new Rectangle(45, (int)bounds.Y + 255, 85, 85);
        }

        //Play sound
        Random random = new Random();
        var soundManager = Game.Services.GetService(typeof(ISoundManager<MenuSounds>)) as ISoundManager<MenuSounds>;
        soundManager.PlaySound((MenuSounds)random.Next((int)MenuSounds.Keystroke1, (int)MenuSounds.Keystroke3 + 1));
      });

      //SPACE BUTTON
      Extra_buttons[2] = new Button(Game, @"Images//Menu//button2", new Rectangle(285, (int)bounds.Y + 375, 270, 50), Color.Blue, "large_font",Locale.Strings.KeyBoardSpace, Color.White);
      AddButton(Extra_buttons[2], () =>
      {
        color = Extra_buttons[2].color;
        PressedOn = true;
        ExtraOn = true;
        Epres = 2;

        if (word.Length > 0)
          word += " ";

        //Play sound
        Random random = new Random();
        var soundManager = Game.Services.GetService(typeof(ISoundManager<MenuSounds>)) as ISoundManager<MenuSounds>;
        soundManager.PlaySound((MenuSounds)random.Next((int)MenuSounds.Keystroke1, (int)MenuSounds.Keystroke3 + 1));
      });

      //DELETE BUTTON
      Extra_buttons[3] = new Button(Game, @"Images//Menu//button2", new Rectangle(570, (int)bounds.Y + StartHeight + 106 + (HeightGap * 2), 120, 50), Color.Red, "large_font", Locale.Strings.KeyBoardDelete, Color.White);
      AddButton(Extra_buttons[3], () =>
      {
        color = Extra_buttons[3].color;
        PressedOn = true;
        ExtraOn = true;
        Epres = 3;

        if (word.Length > 0)
          word = word.Substring(0, word.Count() - 1);

        // Play sound
        Random random = new Random();
        var soundManager = Game.Services.GetService(typeof(ISoundManager<MenuSounds>)) as ISoundManager<MenuSounds>;
        soundManager.PlaySound((MenuSounds)random.Next((int)MenuSounds.Keystroke1, (int)MenuSounds.Keystroke3 + 1));
      });

      Back = new Button(Game, @"Images//Menu//button2", new Rectangle(50, (int)bounds.Y + 400, 150, 45), Color.Green, "small_font", Locale.Strings.Cancel, Color.White);
      AddButton(Back, () =>
      {
        Back.touched = true;        
      });

      Save = new Button(Game, @"Images//Menu//button2", new Rectangle(630, (int)bounds.Y + 400, 140, 45), Color.Green, "small_font", Locale.Strings.Save, Color.White, new Color(0, 0, 0, 0));
      AddButton(Save, () =>
      {

        if (word.Length > 0)
          Save.touched = true;
        else
        {
          Save.touched = true;
          Save.TouchColor = Color.Red;
        }


        //Easter Egg
        if (word.Equals("Carousel") || word.Equals("CAROUSEL") || word.Equals("carousel"))
        {
          var SoundManager = Game.Services.GetService(typeof(ISoundManager<MenuSounds>)) as ISoundManager<MenuSounds>;
          SoundManager.PlaySound(MenuSounds.Logo, 0.6f, 0.5f, 0.0f);
        }

        //Prevents the user to call himself default as the default profile
        if (word.Equals("default"))
          word = word.ElementAt(0).ToString().ToUpper() + "efault";

        if (word.Length > 0)
        {
          // Save the new profile
          Profile profile = new Profile { id = Game.GetNextAvailableUId(), username = word };
          Game.SaveProfile(profile);
          Game.GetContext().currentProfile = profile;
          // Save a default configuration file for this profile
          Game.GetContext().currentConfig = SaveUtils.defaultConfig;
          Game.SaveConfig(SaveUtils.defaultConfig, profile.id);
          // Update information in the defaults
          DefaultInfo info = Game.LoadDefaults();
          info.lastProfileId = profile.id;
          Game.SaveDefaults(info);
        }

      });
    }

    bool hasProfile = true;
    int counter = 4;
    public override void Update(GameTime gameTime)
    {
      // cotrollo per far ritornare pulsante back e cancel al component da dove sono stati chiamati
      if(!fromProfile)
      {
      if (Profiles.Count < 1) 
        hasProfile = false;
      else
        hasProfile = true;
      }

      if(Save.touched)
      {    
          counter--;
          if (counter < 0)
          {
            if (word.Length > 0)
            {
              Direction = -1;
              Animated = true;
              ProfileCreated = true;  
            }
            else
            {
              Save.touched = true;
              //Save.TouchColor = new Color(0, 0, 0, 0);
            }                    
        }
      }

      if (Back.touched)
      {
        counter--;
        if (counter < 4)
        {
          Epres = 0;
          Direction = -1;
          Animated = true;
        }
      }

      // Input: back button pressed
      if (((Game1)Game).IsBackButtonPressed())
      {        
        Epres = 0;
        Direction = -1;
        Animated = true;
       }

      if (PressedOn)
      {
        if (ExtraOn)        
          Extra_buttons[Epres].color = Color.Olive;
        else   
          keyboard_buttons[Ipres].color = Color.Olive;
        
        Tpres++;
        if (Tpres > 5)
        {
          ExtraOn = false;
          Tpres = 0;
          PressedOn = false;
        }
      }
      else
      {
        if(Ipres > 0)
          keyboard_buttons[Ipres].color = colorBtn;

        if(Epres > 0)
          Extra_buttons[Epres].color = color;
      }

      
      if (ShiftOn)
      {
        for (int i = 1; i < 27; i++)
          keyboard_buttons[i].message = keyboard_buttons[i].message.ToLower();

      }
      else
      {
        for (int i = 1; i < 27; i++)
          keyboard_buttons[i].message = WordArray[i - 1];
      }

      if (Animated)
      {
        bounds.Y += Direction * 35;

        foreach (Button b in (from cb in buttons select cb.b))
        {
          b.bounds.Y += Direction * 35;
        }

        if (bounds.Y > 0 && Direction == 1)
        {
          Animated = false;
          int offset = bounds.Y;
          bounds.Y = 0;

          foreach (Button b in (from cb in buttons select cb.b))
          {
            b.bounds.Y += -Direction * offset;
          }

        }

        if (bounds.Y < savedPos.Y)
        {
          if (ProfileCreated)
          {
            if (OnSaveClicked != null)
              OnSaveClicked();
          }
          else
          {
            if(hasProfile)
              {
            if (OnExitClicked != null)
              OnExitClicked();
              }
            else
            {
              if (OnExitClickedNoProfile != null)
                OnExitClickedNoProfile();
              }
          }
        }
      }

      

      base.Update(gameTime);
    }

    
    public override void Draw(GameTime gameTime)
    {
      base.Draw(gameTime);

      spriteBatch.Begin();
      spriteBatch.Draw(Game.Content.Load<Texture2D>(@"Images//Game//roundedBox"), new Rectangle(230, 75 + bounds.Y, 340, 60), new Color(0, 0, 0, 100));
      spriteBatch.Draw(Game.Content.Load<Texture2D>(@"Images//Game//roundedBox"), new Rectangle(235, 70 + bounds.Y, 340, 60), Color.PaleGreen);
      spriteBatch.DrawString(Game.Content.Load<SpriteFont>("large_font"), "" + word, new Vector2(270, 70 + bounds.Y), Color.Blue);
      spriteBatch.DrawString(Game.Content.Load<SpriteFont>("Baveuse1_font"), Locale.Strings.EnterName, new Vector2(190, bounds.Y), Color.Black);

      spriteBatch.End();
    }

    public event MenuEvent OnExitClicked;
    public event MenuEvent OnSaveClicked;
    public event MenuEvent OnExitClickedNoProfile;
  }
}
